﻿using AuthorityManagement.Model;
using AuthorityManagement.Model.Dto;
using AuthorityManagement.Model.Dto.FileDto;
using AuthorityManagement.Model.Dto.RoleDto;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using NetTaste;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OracleInternal.Secure.Network;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using System.Security.Cryptography;
using MD5 = System.Security.Cryptography.MD5;
using System.Text;
using System.IO;
using File = AuthorityManagement.Model.File;
using static AuthorityManagement.Controllers.WeatherForecastController;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace AuthorityManagement.Controllers
{

    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        private readonly ISqlSugarClient _Db;
        public UserController(ISqlSugarClient db)
        {
            _Db = db;
        }
        /// <summary>
        /// 根据id获取用户数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("GetUserId")]
        public dynamic GetUserId(string id)
        {
            var data = _Db.Queryable<User>().Where(it => it.Id.Equals(id)).Select(it => new UserInfoOutput { Id = it.Id, UserCode = it.UserCode, UserName = it.UserName, Age = it.Age, Sex = it.Sex, Address = it.Address, Phone = it.Phone, Remark = it.Remark, Email = it.Email, Url = it.Url }).ToList();
            return new { list = data };
        }

        // POST api/<UserController>
        /// <summary>
        /// 获取用户列表
        /// </summary>
        /// <param name="value"></param>
        [HttpPost("GetUserList")]
        public dynamic GetUserList([FromBody] UserListQueryInput input)
        {
            var data1 = _Db.Queryable<User>()
                .WhereIF(!string.IsNullOrEmpty(input.UserCode), it => it.UserCode.Contains(input.UserCode))
                .WhereIF(!string.IsNullOrEmpty(input.UserName), it => it.UserName.Contains(input.UserName))
                .Select(it => new UserListOutput
                {
                    Id = it.Id,
                    UserCode = it.UserCode,
                    UserName = it.UserName,
                    Address = it.Address,
                    Age = it.Age,
                    Sex = it.Sex,
                    Status = it.Status,
                    Url = it.Url,
                    Phone = it.Phone,
                    Remark = it.Remark,
                    Sort = it.Sort,
                    Email = it.Email,
                }).OrderByIF(!string.IsNullOrEmpty(input.sidx), it => input.sidx + " " + input.sort).ToSql();
            var data = _Db.Queryable<User>()
                .WhereIF(!string.IsNullOrEmpty(input.UserCode), it => it.UserCode.Contains(input.UserCode))
                .WhereIF(!string.IsNullOrEmpty(input.UserName), it => it.UserName.Contains(input.UserName))
                .Select<UserListOutput>().OrderByIF(!string.IsNullOrEmpty(input.sidx), it => input.sidx + " " + input.sort).ToPageList(input.currentpage, input.pagesize);
            //.Select(it => new UserListOutput
            //{
            //    Id = it.Id,
            //    UserCode = it.UserCode,
            //    UserName = it.UserName,
            //    Address = it.Address,
            //    Age = it.Age,
            //    Sex = it.Sex,
            //    Status = it.Status,
            //    Url = it.Url,
            //    Phone = it.Phone,
            //    Remark = it.Remark,
            //    Sort = it.Sort,
            //    Email = it.Email,
            //}).OrderByIF(!string.IsNullOrEmpty(input.sidx),it=>input.sidx +" " +input.sort).ToPageList(input.currentpage, input.pagesize);
            return new { list = data, count = data.Count };
        }

        /// <summary>
        /// 添加编辑方法
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="input">参数</param>
        /// <returns></returns>
        [HttpPost("Create")]
        public dynamic Create([FromBody] UserCrInput input)
        {
            input.PassWord = Md5Helper(input.PassWord);
            //适配User
            var data = input.Adapt<User>();
            data.Id = Guid.NewGuid().ToString();
            var adddata = _Db.Insertable(data).ExecuteCommand();
            if (adddata < 1)
            {
                return new { Message = "新增失败！", Success = false };
            }
            else
            {
                return new { Message = "新增成功！", Success = true };
            }
        }

        /// <summary>
        /// 编辑用户信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("UpdateUser")]
        public dynamic Update(string id, [FromBody] UserUpInput input)
        {
            var data = input.Adapt<User>();
            var count = _Db.Updateable(data).UpdateColumns(it => new User() { Id = it.Id, Url = it.Url, UserCode = it.UserCode, UserName = it.UserName, Phone = it.Phone, Address = it.Address, Sex = it.Sex, Age = it.Age, Status = it.Status, Remark = it.Remark, Email = it.Email }).Where(it => it.Id == data.Id).ExecuteCommand();
            if (count < 1)
            {
                return new { Message = "编辑失败！", Success = false };
            }
            else
            {
                return new { Message = "编辑成功！", Success = true };
            }
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id"></param>
        [HttpDelete("Delete")]
        public dynamic Delete(string id)
        {
            var data = _Db.Updateable<User>().SetColumns(it => new User() { DeleteMark = "1", DeleteTime = DateTime.Now }).Where(it => it.Id == id).ExecuteCommand();
            if (data < 0)
            {
                return new { Message = "删除失败！", Success = false };
            }
            return new { Message = "删除成功！", Success = true };
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <returns></returns>
        [HttpPost("ResetPassWord")]
        public dynamic ResetPassWord(string id)
        {
            var data = _Db.Queryable<User>().Where(it => it.Id == id).Count();
            if (data < 0)
            {
                return Ok("未查到相关数据！");
            }
            //更新
            var isOk = _Db.Updateable<User>().SetColumns(it => new User() { PassWord = "123456" }).Where(it => it.Id == id).ExecuteCommand();
            if (!(isOk > 0))
            {
                return new { Message = "重置密码失败！", Success = false };
            }
            else
            {
                return new { Message = "重置密码成功！", Success = true };
            }
        }

        /// <summary>
        /// 用户状态的修改
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="status">状态</param>
        /// <returns></returns>
        [HttpPost("StatusUpdate")]
        public dynamic StatusUpdate(string id, string status)
        {
            var isOk = _Db.Updateable<User>().SetColumns(it => new User() { Status = status }).Where(it => it.Id == id).ExecuteCommand();
            if (!(isOk > 0)) { return new { Message = "状态修改失败！", Success = false }; }
            return new { Message = "状态修改成功！", Success = true };

        }

        /// <summary>
        /// 获取角色数据
        /// </summary>
        /// <returns></returns>
        [HttpPost("GetAllRoleList")]
        public dynamic GetAllRoleList()
        {
            var roleData = _Db.Queryable<Role>().Where(it => it.DeleteMark == null).Select(it => new RoleListOutput() { key = Convert.ToInt32(it.Id), label = it.RoleName }).ToList();
            return roleData;
        }

        /// <summary>
        /// 获取用户拥有的角色.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("GetUserHaveRoleList")]
        public List<RoleDt> GetUserHaveRoleList(string id)
        {
            var userhaverolelist = _Db.Queryable<User_Role>().Where(it => it.UserId == id && it.DeleteMark == null).Select(it => new RoleDt()
            {
                key = Convert.ToInt32(it.RoleId),
            }).ToList();
            return userhaverolelist;
        }

        /// <summary>
        /// 保存用户角色权限
        /// </summary>
        /// <param name="id">用户id</param>
        /// <param name="values">values</param>
        /// <returns></returns>
        [HttpPost("SaveUserRoleAuthority")]
        public dynamic SaveUserRoleAuthority(string id, [FromBody] List<int> values)
        {
            //首先把该用户的数据逻辑删除
            if (_Db.Queryable<User_Role>().Where(it => it.UserId == id && it.DeleteMark == null).Any())
            {
                _Db.Updateable<User_Role>().SetColumns(it => new User_Role() { DeleteMark = "1", DeleteTime = DateTime.Now, DeleteUser = "admin" }).Where(it => it.UserId == id).ExecuteCommand();
            }
            List<User_Role> userrolelist = new List<User_Role>();
            for (int i = 0; i < values.Count(); i++)
            {
                User_Role userRole = new User_Role();
                userRole.Id = Guid.NewGuid().ToString();
                userRole.UserId = id;
                userRole.RoleId = values[i].ToString();
                userRole.CreateTime = DateTime.Now;
                userRole.CreateUser = "admin";
                userRole.DeleteMark = null;
                userrolelist.Add(userRole);
            }
            var isOk = _Db.Insertable(userrolelist).ExecuteCommand();
            if (!(isOk > 0))
            {
                return new { Message = "添加角色失败！", Success = false };
            }
            else
            {
                return new { Message = "添加角色成功！", Success = true };
            }
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="input">参数</param>
        /// <returns></returns>
        [HttpPost("UpdatePassWord")]
        public dynamic UpdatePassWord([FromBody] UserDto input)
        {
            //根据用户id查找该用户的密码
            var oldpassword = _Db.Queryable<User>().Where(it => it.Id == input.Id && it.DeleteMark == null).Select(it => it.PassWord).First();
            if (oldpassword != input.OldPassWord)
            {
                return new { Message = "密码不正确,请输入正确的密码", Success = false };
            }
            else
            {
                var isOk = _Db.Updateable<User>().SetColumns(it => new User() { PassWord = input.NewPassWord, LastModifyTime = DateTime.Now, LastModifyUser = "admin" }).Where(it => it.Id == input.Id).ExecuteCommand();
                if (!(isOk > 0))
                {
                    return new { Message = "修改密码失败！", Success = false };
                }
                else
                {
                    return new { Message = "修改密码成功！", Success = true };
                }
            }

        }

        /// <summary>
        /// 测试接口
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("Test")]
        public dynamic Test([FromBody] List<Person> input)
        {
            //实体转换
            var adapt = _Db.Reportable<Person>(input).ToQueryable();
            var data = _Db.Queryable<User>().InnerJoin(adapt, (a, b) => a.Id == b.Id).Select((a, b) => "用户编号：" + a.UserCode + "，用户名：" + b.Name).ToList();
            return data;
        }

        /// <summary>
        /// 新建文件信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("UpFile")]
        public dynamic UpFile([FromBody] FileCrInput input)
        {
            //序列化数据
            string fileinfo = JsonConvert.SerializeObject(input.FileInfo);
            File file = new File()
            {
                Id = Guid.NewGuid().ToString(),
                FileInfo = fileinfo,
                Type = input.Type,
                Remark = input.Remark,
            };

            //var data = input.Adapt<File>();
            // data.Id=Guid.NewGuid().ToString();
            var isOk = _Db.Insertable(file).ExecuteCommand();
            if (!(isOk > 0))
            {
                return new { Message = "新建文件失败！", Success = false };
            }
            else
            {
                return new { Message = "新建文件成功！", Success = true };
            }

        }

        /// <summary>
        /// 获取文件信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("GetFile")]
        [AllowAnonymous]
        public async Task<dynamic> GetFile(string id)
        {
            var data = await _Db.Queryable<File>().Where(it => it.Id == id).Select(it => new File() { FileInfo = it.FileInfo, Remark = it.Remark, Type = it.Type }).FirstAsync();
            //反序列化数据
            List<FileControlsModel> json = JsonConvert.DeserializeObject<List<FileControlsModel>>(data.FileInfo);
            //声名一个返回对象
            FileDto dto = new FileDto()
            {
                fileInfo = json,
                remark = data.Remark,
                type = data.Type,
            };
            return dto;
        }

        /// <summary>
        /// MD5帮助类
        /// </summary>
        /// <param name="data">加密数据</param>
        /// <returns></returns>
        [HttpPost("Md5Helper")]
        public dynamic Md5Helper(string data)
        {
            using (MD5 md5 = MD5.Create())
            {
                // 将字符串转换为字节数组  
                byte[] inputBytes = Encoding.UTF8.GetBytes(data);

                // 计算哈希值  
                byte[] hashBytes = md5.ComputeHash(inputBytes);

                // 将哈希值转换为十六进制字符串  
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < hashBytes.Length; i++)
                {
                    sb.Append(hashBytes[i].ToString("x2"));
                }
                string hashString = sb.ToString();
                return hashString;
            }
        }
        //public  class Md5Helper
        //{
        //        using (MD5 md5=MD5.Create())
        //        {

        //        }}
        //}
        /// <summary>
        /// 获取树型菜单.
        /// </summary>
        /// <returns></returns>
        [HttpPost("GetTreeList")]
        [AllowAnonymous]
        public async Task<dynamic> GetTreeList()
        
        {
            var data = await _Db.Queryable<Menu>().ToTreeAsync(it => it.Children, it => it.ParentId, -1);
            return data;
        }

        /// <summary>
        /// 获取角色拥有的菜单权限
        /// </summary>
        /// <param name="RoleId">角色id</param>
        /// <returns></returns>
        [HttpGet("GetRoleMenu")]
        public async Task<dynamic> GetRoleMenu(string RoleId)
        {
            var data = await _Db.Queryable<Role_Menu>().Where(it => it.RoleId == RoleId).Select(it => new { id = it.MenuId, }).ToListAsync();
            return data;
        }


        /// <summary>
        /// 存储过程的使用
        /// </summary>
        /// <param name="ids">表的id用,拼接的字符串</param>
        /// <returns></returns>
        [HttpPost("Procedure")]
        public async Task<dynamic> Procedure(string ids)
        {
            var Ids = new SugarParameter("@ids", ids);
            var name = new SugarParameter("@Name", null, true);//output设置为true
            var count = new SugarParameter("@Count", null, true);

            //var parameters = new List<SugarParameter>(){ new SugarParameter("@ids", ids),new SugarParameter("@Name", null,true), new SugarParameter("@Count", null,true) };
            var parameters = new List<SugarParameter>()
{
    new SugarParameter("@参数名1", ids),
    new SugarParameter("@参数名2", ids),
};

            //执行存储过程
            var dt = await _Db.Ado.UseStoredProcedure().GetDataTableAsync("deletestudentids5", Ids, name, count);//返回dt
            //var dt = await _Db.Ado.UseStoredProcedure().GetDataTableAsync("deletestudentids5", parameters[0], parameters[1], parameters[2]);
            //返回参数
            var name1 = name.Value;
            var count1 = count.Value;
            return new { Name = name1, Count = count1 };
        }

        /// <summary>
        /// 根据用户获取角色所属菜单(树形)
        /// </summary>
        /// <param name="userCode"></param>
        /// <returns></returns>
        [HttpGet("GetUserTreeMenu")]
        public async Task<dynamic> GetUserTreeMenu(string userCode)
        {
            //用户拥有的所有菜单集合
            var userRoleMenu = await _Db.Queryable<User, User_Role, Role_Menu, Menu>((a, b, c, d) =>
            new JoinQueryInfos(JoinType.Left, a.Id == b.UserId, JoinType.Left, b.RoleId == c.RoleId, JoinType.Left, c.MenuId == d.Id))
                .Where((a, b, c, d) => a.UserCode == userCode)
                .Select((a, b, c, d) => new MenuDto { Id = d.Id, RoleId = c.RoleId, MennuCode = d.MenuCode, title = d.MenuName, path = d.URL, ParentId = d.ParentId }).ToListAsync();
            //List<MenuDto> tree = new List<MenuDto>();
            //foreach (var item in userRoleMenu)
            //{
            //    tree.Add(item);
            //}
            var treelist = GetMenuTree(userRoleMenu, "-1");
            return new { treelist = treelist, menulist = userRoleMenu };
        }
        private static List<MenuDto> GetMenuTree(List<MenuDto> list, string pid)
        {
            List<MenuDto> tree = new List<MenuDto>();
            var children = list.Where(m => m.ParentId == pid).ToList();
            if (children.Count > 0)
            {
                for (var i = 0; i < children.Count; i++)
                {
                    MenuDto itemMenu = new MenuDto();
                    itemMenu.Id = children[i].Id;
                    itemMenu.RoleId = children[i].RoleId;
                    itemMenu.ParentId = children[i].ParentId;
                    itemMenu.MennuCode = children[i].MennuCode;
                    itemMenu.title = children[i].title;
                    itemMenu.path = children[i].path;
                    itemMenu.Children = GetMenuTree(list, children[i].Id);
                    tree.Add(itemMenu);
                }
            }
            return tree;
        }

    }
    public class FileDto
    {
        public string fileJson { get; set; }
        public List<FileControlsModel> fileInfo { get; set; }
        public string type { get; set; }
        public string remark { get; set; }
    }
    public class RoleDt
    {
        public int key { get; set; }
    }

    public class UserDto
    {
        /// <summary>
        /// 用户id
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        /// 老密码
        /// </summary>

        public string OldPassWord { get; set; }

        /// <summary>
        /// 新密码
        /// </summary>

        public string NewPassWord { get; set; }
    }

    /// <summary>
    /// 测试
    /// </summary>
    public class Person
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Age { get; set; }
    }
    public class MenuDto
    {
        public string Id { get; set; }
        public string RoleId { get; set; }
        public string MennuCode { get; set; }
        public string title { get; set; }
        public string path { get; set; }
        public string ParentId { get; set; }
        public List<MenuDto> Children { get; set; } = new List<MenuDto>();
    }

}
